Podsumowanie

Analiza danych dotyczących baterii wykazała, że: - Najpowszechniej występują baterie litowo-jonowe. Posiadają one bardzo korzystny współczynnik gęstości energetycznej do ich masy, co może przekładać się na ich popularność, gdyż mogą być stosowane w lekkich urządzeniach mobilnych. - Atrybuty opisujące gęstość energii i pojemność względem masy i objęctości są silnie skorelowane. - Model liniowy nie daje satysfakcjonujących predykcji stabilności baterii.

Wykorzystane biblioteki

library(dplyr)
library(ggcorrplot)
library(ggplot2)
library(ggthemes)
library(gridExtra)
library(kableExtra)
library(plotly)
library(caret)

Wczytanie danych

Dane wczytane z pliku mp.batteries.csv.

df <- read.csv("mp_batteries.csv")
Battery.ID Battery.Formula Working.Ion Formula.Charge Formula.Discharge Max.Delta.Volume Average.Voltage Gravimetric.Capacity Volumetric.Capacity Gravimetric.Energy Volumetric.Energy Atomic.Fraction.Charge Atomic.Fraction.Discharge Stability.Charge Stability.Discharge Steps Max.Voltage.Step
mp-30_Al Al0-2Cu Al Cu Al2Cu 3.043399 0.0890331 1368.481 5562.790 121.84009 495.27253 0.0 0.6666667 0.0000000 0.0000000 1 0
mp-1022721_Al Al1-3Cu Al AlCu Al3Cu 1.243653 -0.0215863 1112.937 4418.980 -24.02423 -95.38962 0.5 0.7500000 0.0740612 0.0962458 1 0
mp-8637_Al Al0-5Mo Al Mo Al5Mo 4.762574 0.1227568 1741.504 7175.702 213.78156 880.86651 0.0 0.8333333 0.4114601 0.0452120 1 0
mp-129_Al Al0-12Mo Al Mo Al12Mo 12.723893 0.0431214 2298.811 7346.232 99.12801 316.78006 0.0 0.9230769 0.0000000 0.0114456 1 0
mp-91_Al Al0-12W Al W Al12W 12.494598 0.0292342 1900.745 7332.719 55.56677 214.36621 0.0 0.9230769 0.0000000 0.0000000 1 0
mp-1055908_Al Al0-12Mn Al Mn MnAl12 18.236156 0.0397314 2547.693 7592.916 101.22330 301.67688 0.0 0.9230769 0.1454643 0.0000000 1 0

Podsumowanie zbioru

Zbiór zawiera dane o materiałach wykorzystywanych w bateriach. Uwzględnia ich skład chemiczny i parametry wydajnościowe.

Liczność zbioru

Zbiór danych posiada:

  • 4351 wierszy
  • 17 atrybutów
  • 0 Brakujących wartości

Atrybuty

  • Battery ID: Identyfikator baterii.
  • Battery Formula: Wzór chemiczny materiału baterii.
  • Working Ion: Główny jon, który odpowiada za transport ładunku w baterii.
  • Formula Charge: Wzór chemiczny materiału baterii w stanie naładowanym.
  • Formula Discharge: Wzór chemiczny materiału baterii w stanie rozładowanym.
  • Max Delta Volume: Zmiana objętości w % dla danego kroku napięcia za pomocą wzoru: max(charge, discharge)/min(charge, discharge) -1.
  • Average Voltage: Średnie napięcie dla poszczególnego kroku napięcia.
  • Gravimetric Capacity: Pojemność grawimetryczna, czyli ilość energii na jednostkę masy (mAh/g).
  • Volumetric Capacity: Pojemność wolumetryczna, czyli ilość energii na jednostkę objętości (mAh/cm³).
  • Gravimetric Energy: Gęstość energii w odniesieniu do masy baterii (Wh/kg).
  • Volumetric Energy: Gęstość energii w odniesieniu do objętości baterii (Wh/L).
  • Atomic Fraction Charge: Udział atomowy składników w stanie naładowanym.
  • Atomic Fraction Discharge: Udział atomowy składników w stanie rozładowanym.
  • Stability Charge: Wskaźnik stabilności materiału w stanie naładowanym.
  • Stability Discharge: Wskaźnik stabilności materiału w stanie rozładowanym.
  • Steps: Liczba odrębnych kroków napięcia od pełnego naładowania do rozładowania, oparta na stabilnych stanach pośrednich.
  • Max Voltage Step: Maksymalna bezwzględna różnica między sąsiednimi krokami napięcia.

Źródło: “Programowanie w R: Projekt - Wymagania”

Podstawowe statystyki

Battery.ID Battery.Formula Working.Ion Formula.Charge Formula.Discharge Max.Delta.Volume Average.Voltage Gravimetric.Capacity Volumetric.Capacity Gravimetric.Energy Volumetric.Energy Atomic.Fraction.Charge Atomic.Fraction.Discharge Stability.Charge Stability.Discharge Steps Max.Voltage.Step
Length:4351 Length:4351 Length:4351 Length:4351 Length:4351 Min. : 0.00002 Min. :-7.755 Min. : 5.176 Min. : 24.08 Min. :-583.5 Min. :-2208.1 Min. :0.00000 Min. :0.007407 Min. :0.00000 Min. :0.00000 Min. :1.000 Min. : 0.0000
Class :character Class :character Class :character Class :character Class :character 1st Qu.: 0.01747 1st Qu.: 2.226 1st Qu.: 88.108 1st Qu.: 311.62 1st Qu.: 211.7 1st Qu.: 821.6 1st Qu.:0.00000 1st Qu.:0.086957 1st Qu.:0.03301 1st Qu.:0.01952 1st Qu.:1.000 1st Qu.: 0.0000
Mode :character Mode :character Mode :character Mode :character Mode :character Median : 0.04203 Median : 3.301 Median : 130.691 Median : 507.03 Median : 401.8 Median : 1463.8 Median :0.00000 Median :0.142857 Median :0.07319 Median :0.04878 Median :1.000 Median : 0.0000
NA NA NA NA NA Mean : 0.37531 Mean : 3.083 Mean : 158.291 Mean : 610.62 Mean : 444.1 Mean : 1664.0 Mean :0.03986 Mean :0.159077 Mean :0.14257 Mean :0.12207 Mean :1.167 Mean : 0.1503
NA NA NA NA NA 3rd Qu.: 0.08595 3rd Qu.: 4.019 3rd Qu.: 187.600 3rd Qu.: 722.75 3rd Qu.: 614.4 3rd Qu.: 2252.3 3rd Qu.:0.04762 3rd Qu.:0.200000 3rd Qu.:0.13160 3rd Qu.:0.09299 3rd Qu.:1.000 3rd Qu.: 0.0000
NA NA NA NA NA Max. :293.19322 Max. :54.569 Max. :2557.627 Max. :7619.19 Max. :5926.9 Max. :18305.9 Max. :0.90909 Max. :0.993333 Max. :6.48710 Max. :6.27781 Max. :6.000 Max. :26.9607
Unique: 4351 Unique: 3301 Unique: 10 Unique: 2096 Unique: 3173 Unique: 4342 Unique: 4351 Unique: 3330 Unique: 4342 Unique: 4351 Unique: 4351 Unique: 126 Unique: 192 Unique: 3050 Unique: 3933 Unique: 6 Unique: 600

Czyszczenie i przegląd atrybutów

Atrybuty numeryczne

W zbiorze występują następujące atrybuty numeryczne:

Jak widać dystrybucja atrybutów zawiera wiele outlierów ponad trzecim kwartylem. Można je usunąć. Wyjątkiem będzie kolumna Steps, ponieważ zawiera dyskretne wartości, których niektóre wartości występują zacząco rzadziej. Usunięcie outlierów na podstawie tego atrybutu może doprowadzić do utraty istotnych danych. Podobnie usuwnie

outlier_detection_param = 3.2

remove_outliers <- function(df, columns) { 
  for (col in columns) { 
    Q3 <- quantile(df[[col]], 0.75) 
    IQR <- IQR(df[[col]])
    threshold <- Q3 + outlier_detection_param * IQR
    ret_df <- df[df[[col]] <= threshold, ] 
  } 
  return(ret_df) 
}

columns_to_clean <- setdiff(numeric_columns_names, c("Steps", "Max.Voltage.Step"))
df_clean <-
  remove_outliers(df, columns_to_clean) %>%
  filter(
     Max.Delta.Volume < 0.5,
     Average.Voltage > -2, Average.Voltage  < 9,
     Gravimetric.Energy < 2000,
     Volumetric.Energy < 6500,
     Volumetric.Capacity < 2000,
     Atomic.Fraction.Charge < 0.4,
     Stability.Charge < 0.6,
     Max.Voltage.Step < 2
  )

Wybór outlierów do usunięcia polega na standardowej metodzie wykorzystującej trzeci kwartyl i rozstęp międzykwartylowy i usunięcia wierszy w których te outliery się znajdują. Analiza wykresów pudełkowych wskazuje, że outliery występują niemal wyłącznie w górnym przedziale wartośści atrybutów. Dlatego też do wykrywania outlierów wykorzystano następujący wzór:

\[ O = \{x: \exists_{a \text{ jest atrybutem } x} a > Q3 + 3.2 * IQR \} \]

Parametr 3.2 został dobrany tak, aby w zbiorze pozostało około 90% wierszy.

Ponadto, dodatkowe pojedyncze outliery zostały usunięte poprzez ręczną analizę wykresów pudełkowych.

Po usunięciu outlierów zbiór posiada 3896 wierszy, co stanowi 90% oryginalnego zbioru.

Atrybuty nominalne

Atrybuty nominalne:

  • Battery.ID (3896 unikalnych wartości)
  • Battery.Formula (2950 unikalnych wartości)
  • Working.Ion (10 unikalnych wartości)
  • Formula.Charge (1917 unikalnych wartości)
  • Formula.Discharge (2837 unikalnych wartości)

Tylko kolumna Working.Ion posiada liczbę unikalnych wartości która nadaje się do wizualizacji.

Zdecydowaną większość baterii w zbiorze stanowią baterie litowo-jonowe.

Analiza atrybutów

Napięcie względem głównego jonu baterii

Pojemność względem głównego jonu baterii

Można zauważyć, że ogniwa litowo-jonowe charakteryzują się średnio większą pojemnością na jednostkę masy (są lekkie), a cynkowe i itrowe mają korzystniejszy stosunek objętości do pojemności (są mniejsze).

Energia względem głównego jonu baterii

Bardzo podobną zależność można zauważyć jeśli chodzi o energię baterii. Litowe posiadają więcej energii wziędem jednostki masy, a cynkowe i itrowe względem objętości.

Można rówież zauważyć, że wszystkie cztery atrybuty posiadają silną korelację ze sobą.

Wskaźniki stabilności względem głównego jonu baterii

Analiza wykresu nie pozwala stwierdzić zależności między stabilnością a użytym jonem.

Korelacje między zmiennymi

Współczynnik korelacji zwykle uznaje się za wysoki gdy jego wartość bezwzględna przekracza 0.7.

Biorąc pod uwagę opisy atrybutów, można spodziewać się silnej korelacji między parami: Gravimetric/Volumetric Capacity i Energy. Odnoszą się do podobnego pojęcia dotyczącego pojemności i gęstości energii w baterii wyrażonych względem różnych jednostek. Można również spodziewać się korelacji między gęstością i pojemnością baterii - im większa gęstość, tym większa pojemność na jednostkę masy.

Atrybut 1 Atrybut 2 Współczynnik korelacji
Gravimetric.Energy Volumetric.Energy 0.912
Gravimetric.Capacity Volumetric.Capacity 0.873
Gravimetric.Capacity Gravimetric.Energy 0.771
Gravimetric.Capacity Volumetric.Energy 0.762
Steps Max.Voltage.Step 0.756
Volumetric.Capacity Volumetric.Energy 0.737
Atomic.Fraction.Charge Atomic.Fraction.Discharge 0.703

Oczekiwane korelacje wystąpiły z najwyższymi wartościami współczynnika.

Steps i Max Voltage Step

Wysoką korelację wykazały atrybuty Steps i Max Voltage Step. Możliwe że jest to spowodowane rozkładem wartości skoncentrowanym w znacznym stopniu na podobnych wartościach.

  ggplotly(
    ggplot(df_clean, aes(Steps,Max.Voltage.Step)) +
      geom_point(position = position_jitter(0.2, 0.17))  +
      geom_smooth(method="lm") + 
      theme_minimal()
  )

Na wykresie można zauważyć że wysoka korelacja jest wynikiem bardzo dużej liczby instancji z parami wartości Steps = 1 i Max Voltage Step = 0, które dominują w zbiorze. Nie uznawałbym tego wyniku za znaczący.

Atomic Fraction Charge i Discharge

Wysoką korelację wykazały również atrybuty Atomic Fraction Charge i Atomic Fraction Discharge.

  ggplotly(
    ggplot(df_clean, aes(Atomic.Fraction.Charge, Atomic.Fraction.Discharge)) +
      geom_point(position = position_jitter())  +
      geom_smooth(method="lm") + 
      theme_minimal()
  )

W zbiorze występuje znacząca liczba instancji z Atomic Fraction Charge = 0. Ten wynik można interpretować jako brak udzału atomowego składników w stanie naładowania.

df_positive_afc <- df_clean %>% 
  filter(Atomic.Fraction.Charge > 0) %>% 
  select(Atomic.Fraction.Charge, Atomic.Fraction.Discharge)

cor_chrg_dschrg <- cor_matrix["Atomic.Fraction.Charge", "Atomic.Fraction.Discharge"]
cor_chrg_dschrg_pos <- cor(df_positive_afc)["Atomic.Fraction.Charge", "Atomic.Fraction.Discharge"]

Pozostałe wartości wykazują jednak silną korelację, tj. o wartości 0.836, w porównaniu do ogólnej wartości korelacji tych kolumn, któa wyniosła 0.703. Można więc przyjąć, że dla Atomic Fraction Charge > 0, istnieje korelacja z Atomic Fraction Discharge.

Przewidywanie dalszych cech

Predykcja stabilności materiału

Do dokonania predykcji stabilności materiału, wykorzystane zostaną następujące atrybuty: - Working Ion - Max Delta Volume - Average Voltage - Gravimetric Energy - Atomic Fraction Charge

Zostały wybrane tak, aby nie brać pod uwagę kilku atrybutów o silnej korelacji. Wykorzystany zostanie model liniowy.

df_x_data <- df_clean %>%
  select(
    Working.Ion, 
    Max.Delta.Volume,
    Average.Voltage, 
    Gravimetric.Energy, 
    Atomic.Fraction.Charge
  )

df_y_result_charge <- df_clean$Stability.Charge
df_y_result_discharge <- df_clean$Stability.Discharge

train_model <- function(x_set, y_set) {
  set.seed(42)
  
  data_index <- createDataPartition(y_set, p = 0.8, list = FALSE)
  x_train <- x_set[data_index,]
  x_test <- x_set[-data_index,]
  y_train <- y_set[data_index]
  y_test <- y_set[-data_index]
  
  model <- lm(y_train ~ ., data = as.data.frame(x_train))  
  list(model = model, x_train = x_train, x_test = x_test, y_train = y_train, y_test = y_test)
}


get_prediction_results <- function(model_list){
  y_pred <- predict(model_list$model, newdata = as.data.frame(model_list$x_test))

  df_results <- data.frame(y_pred, y_test = model_list$y_test)
  
  # Calculate Mean Squared Error (MSE) 
  mse <- mean((model_list$y_test - y_pred)^2) 
  
  prediction_volum <- ggplot(df_results, aes(x = y_test, y = y_pred,
                             text = paste("Actual:", round(y_test, 2), "Predicted:", round(y_pred, 2)))) +
  geom_point() +
  geom_abline(slope = 1, intercept = 0, color = "red") +
  labs(
    x = "Actual",
    y = "Predicted"
  ) +
  theme_minimal()

  list(plot = ggplotly(prediction_volum, tooltip = "text"), mse = mse)
}


model_charge_data <- train_model(df_x_data, df_y_result_charge)
model_discharge_data <- train_model(df_x_data, df_y_result_discharge)

list_charge <- get_prediction_results(model_charge_data)
list_discharge <- get_prediction_results(model_discharge_data)

Predykcja wskaźnika stabilności materiału w stanie naładowanym

MSE: 0.005241

Predykcja wskaźnika stabilności materiału w stanie rozładowanym

MSE: 0.0024106

Model liniowy nie najlepiej nadaje się do predykcji wzkaźnika stabilności materiału ze względu na stosunkowo wysoki współczynnik MSE.

Można ulepszyć model dokonując normalizacji danych, dokonania bardziej restrykcyjnego usunięcia outlierów, wybór innego modelu lub innych atrybutów.